﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using GameNesSL.Cache;

namespace gamenesembedd
{
    using System.IO;
    using System.Net.NetworkInformation;
    using System.Windows.Browser;
    using System.Windows.Threading;
    using nesemu;
    using WebRef;

    public partial class MainPage : UserControl
    {
        private const string QueryGameID = "g";

        public MainPage()
        {
           
            InitializeComponent();
            timer.Interval = TimeSpan.FromSeconds(5);
            timer.Tick += new EventHandler(timer_Tick);
            //timer.Start();
            Application.Current.InstallStateChanged += Current_InstallStateChanged;


            if (Application.Current.IsRunningOutOfBrowser)
            {
                if (NetworkInterface.GetIsNetworkAvailable())
                {
                    UpdateApp();
                    LoadGame();
                }
                else
                {
                    ShowError("network unaivailible");
                    NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
                }
            }
            else
            {
                LoadGame();    
            }
        }

        void timer_Tick(object sender, EventArgs e)
        {
            //Visibility vi = advert.Visibility;
            //advert.Visibility = vi == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;//adv colapsed
            //controls.Visibility = vi == Visibility.Visible ? Visibility.Visible : Visibility.Collapsed;//adv visible
        }

        private void UpdateApp()
        {
            Application.Current.CheckAndDownloadUpdateAsync();
        }

        void Current_InstallStateChanged(object sender, EventArgs e)
        {
            if (Application.Current.InstallState==InstallState.Installed)
            {
                GameIDStorage.WriteGameID(GameID);
            }
        }

        void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
        {
            if (NetworkInterface.GetIsNetworkAvailable())
            {
                UpdateApp();
                HideError();
                LoadGame();
            }
        }

        private bool bloaded = false;

        private void LoadGame()
        {
            if (!bloaded)
            {
                try
                {

                    //Check network access
                    if (GetGameID() != null)
                    {
                        embeddLink.EmbedID = GetGameID();
                        //Loadrom
                        LoadRom();
                    }
                    else
                    {
                        //Error
                        ShowError("game not found");
                    }
                }
                catch (Exception)
                {
                    ShowError("error loading game");
                }
            }
        }

        internal void ShowError(string errortext) 
        {
            game.Visibility = Visibility.Collapsed;
            progress.Visibility = Visibility.Collapsed;
            play.Visibility = Visibility.Collapsed;
            error.Visibility = Visibility.Visible;
            errorText.Text = errortext;
        }

        internal void HideError()
        {
            game.Visibility = Visibility.Collapsed;
            progress.Visibility = Visibility.Visible;
            play.Visibility = Visibility.Collapsed;
            error.Visibility = Visibility.Collapsed;
        }

        readonly DispatcherTimer timer = new DispatcherTimer();

        private string GetGameID()
        {
            string gameid = GameIDStorage.GetGameID();
            try
            {
                if (HtmlPage.IsEnabled && HtmlPage.Document.QueryString != null && HtmlPage.Document.QueryString.ContainsKey(QueryGameID))
                {
                    gameid = HtmlPage.Document.QueryString[QueryGameID];
                }
                else
                {
                    if (Application.Current.Host.InitParams != null &&
                        Application.Current.Host.InitParams.ContainsKey(QueryGameID))
                    {
                        gameid = Application.Current.Host.InitParams[QueryGameID];
                    }
                }
            }
            catch (Exception)
            {
                
            }
            return gameid;
        }

        private void LoadRom()
        {
            //loader!!
            try
            {
                downloader.StreamAvailible += downloader_StreamAvailible;
                downloader.Download(new Uri(string.Format("http://gamenes.net/gamebin.aspx?g={0}", GetGameID())));
            }
            catch (Exception)
            {
                ShowError("error loading game");
            }
            SLWEBSoapClient client = new SLWEBSoapClient();
            client.GetGameNameCompleted+=getGameNameCompleted;
            client.GetGameNameAsync(GetGameID());
                        
        }

        private void getGameNameCompleted(object sender, GetGameNameCompletedEventArgs e)
        {
            try
            {
                if (e.Error == null)
                {
                    Dispatcher.BeginInvoke(() => gameName.Text = e.Result);
                }
            }
            catch
            {}
        }

        private void downloader_StreamAvailible(Stream stream)
        {
            try
            {
                GameLoaded(Cache.Unpack(stream));
            }
            catch (Exception)
            {
                ShowError("error loading game");
            }
        }

        
        

        private void GameLoaded(byte[] loaded)
        {
            try
            {
                this.bloaded = true;
                game.Configure(new GameFieldConfig());
                using (MemoryStream ms = new MemoryStream(loaded))
                {
                    game.LoadRom(ms);
                }
                play.Visibility = Visibility.Visible;
                progress.Visibility = Visibility.Collapsed;
                timer.Stop();
                GameID = GetGameID();
                //Deployment.Current.OutOfBrowserSettings.WindowSettings.Title = "Mario";

                if (Application.Current.IsRunningOutOfBrowser)
                {
                    GameIDStorage.WriteGameID(GameID);
                }

            }
            catch (Exception)
            {
                ShowError("error loading game");
            }
        }

        internal string GameID { get; private set; }


        private void PLay_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            play.Visibility = Visibility.Collapsed;
            embeddLink.Visibility = System.Windows.Visibility.Collapsed;
            StartGame();
        }


        private void Install_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Application.Current.Install();
        }

        private void StartGame()
        {
            try
            {
                game.Visibility = Visibility.Visible;
                menu.Visibility = Visibility.Collapsed;
                game.Start();
            }
            catch (Exception)
            {
                ShowError("game error");
            }
        }


        private void Controls_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Visibility vi = advert.Visibility;
            advert.Visibility = vi == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;//adv colapsed
            controls.Visibility = vi == Visibility.Visible ? Visibility.Visible : Visibility.Collapsed;//adv visible

        }
    }
}
